package com.caiyouxi.pay.payment.weixin;


import com.alibaba.fastjson.JSONObject;
import com.caiyouxi.common.exception.BusinessException;
import com.caiyouxi.common.exception.ErrorCode;
import com.caiyouxi.goods.model.GoodsInfo;
import com.caiyouxi.order.model.OrderBean;
import com.caiyouxi.pay.model.PaymentBean;
import com.caiyouxi.pay.model.PaymentConfigBean;
import com.caiyouxi.pay.payment.weixin.utils.InputStreamUtils;
import com.caiyouxi.pay.payment.weixin.utils.SignUtils;
import com.caiyouxi.pay.payment.weixin.wxpay.CommonUtil;
import com.caiyouxi.pay.payment.weixin.wxpay.Dom4JUtil;
import com.caiyouxi.pay.payment.weixin.wxpay.MD5;
import com.caiyouxi.pay.payment.weixin.wxpay.PayPost;
import com.caiyouxi.pay.service.PayBaseService;
import com.caiyouxi.pay.service.PayLogUtil;
import com.caiyouxi.pay.service.PayServiceImpl;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;


/**
 * 微信支付相关
 */

@Service
public class WxPayService implements PayBaseService
{
	private Logger logger = Logger.getLogger(PayServiceImpl.class);

	@Override
	public JSONObject get_third_pay_resp(PayServiceImpl payService, OrderBean bean, GoodsInfo gInfo, PaymentConfigBean ppb)  throws Exception{

		logger.info("发起微信支付...");

		//发送状态
		String send_status="SUCCESS";
		//发送后交易状态
		String send_trade_status="SUCCESS";
		String error_code="";
		String error_msg="";
		String raw="";
		String result_raw="";



		//获取第三方配置信息
		JSONObject thirid_config = JSONObject.parseObject(ppb.getParam_config());
		String body= bean.getTitle();//商品描述
		String app_id = thirid_config.getString("app_id");//应用ID
		String mch_id = thirid_config.getString("mch_id");//商户号
		String spbill_create_ip = thirid_config.getString("ip");
		String notify_url = thirid_config.getString("notify_url");//终端IP
		int is_support_cred = ppb.getIs_support_creditcard();//是否要以使用信用卡 0不支持
		String wx_pay_api_key = thirid_config.getString("key_private");//微信商户密钥，自己设置的
    	String out_trade_no =bean.getId();//商户订单号
    	int order_money = bean.getTotal_amount();
    	String total_fee= String.valueOf(order_money);//总金额,分
		String sign = "";//签名
	    String trade_type = "APP";//交易类型（取值如下：JSAPI，NATIVE，APP，WAP）
    	String nonce_str = CommonUtil.CreateNoncestr();
    	//拼接原始字符串,KEY=VALUE，安ASCII顺序
		String stringA = "appid=" + app_id + "&body=" + body + "&mch_id=" + mch_id + "&nonce_str="
        + nonce_str + "&notify_url=" + notify_url  + "&out_trade_no=" + out_trade_no + "&spbill_create_ip=" + spbill_create_ip
        + "&total_fee=" + total_fee + "&trade_type=" + trade_type;
		logger.info("is_support_cred: "+is_support_cred);
		if(0==is_support_cred)
		{
			//不支持信用卡
			stringA = "appid=" + app_id + "&body=" + body + "&limit_pay=no_credit"+"&mch_id=" + mch_id + "&nonce_str="
					+ nonce_str + "&notify_url=" + notify_url  + "&out_trade_no=" + out_trade_no + "&spbill_create_ip=" + spbill_create_ip
					+ "&total_fee=" + total_fee + "&trade_type=" + trade_type;
		}
		//拼接密钥
		String stringSignTemp = stringA+"&key="+wx_pay_api_key;
    	
		System.out.println("MD5加密前===  " + stringSignTemp);
		sign = MD5.MD5Encode(stringSignTemp).toUpperCase();
		String xmlData = "<xml><appid>" + app_id + "</appid><body>" + body + "</body><mch_id>"
		            + mch_id + "</mch_id><nonce_str>" + nonce_str
		            + "</nonce_str><notify_url>" + notify_url + "</notify_url><out_trade_no>"
		            + out_trade_no + "</out_trade_no><spbill_create_ip>" + spbill_create_ip
		            + "</spbill_create_ip><total_fee>" + total_fee
		            + "</total_fee><trade_type>" + trade_type + "</trade_type><sign>" + sign + "</sign></xml>";
		if(0==is_support_cred)
		{
			xmlData = "<xml>" +
					"<appid>" + app_id + "</appid>" +
					"<body>" + body + "</body>" +
					"<limit_pay>no_credit</limit_pay>" +
					"<mch_id>" + mch_id + "</mch_id>" +
					"<nonce_str>" + nonce_str+ "</nonce_str>" +
					"<notify_url>" + notify_url + "</notify_url>" +
					"<out_trade_no>"+ out_trade_no + "</out_trade_no>" +
					"<spbill_create_ip>" + spbill_create_ip	+ "</spbill_create_ip>" +
					"<total_fee>" + total_fee+ "</total_fee>" +
					"<trade_type>" + trade_type + "</trade_type>" +
					"<sign>" + sign + "</sign>" +
					"</xml>";
		}

		 System.out.println(" 请求接口前发送的字符 xmlData===  " + xmlData);
		 String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		 raw = xmlData;
	     String result = PayPost.postRequestUrl(url, xmlData);
	     result_raw = result;
	     String returnStr = "fail";
        System.out.println("result==="+result);
        Document document = Dom4JUtil.stringToDocument(result);
        String return_code = Dom4JUtil.getElementAttribute(document, "xml/return_code");
        String prepay_id = "";
		String result_code = Dom4JUtil.getElementAttribute(document, "xml/result_code");
        
        if (null != return_code && "SUCCESS".equals(return_code))
        {

            if (null != result_code && "SUCCESS".equals(result_code))
            {
                returnStr = Dom4JUtil.getElementAttribute(document, "xml/prepay_id");
                prepay_id = returnStr;
            }
        }
        else
		{
			//下单失败
			send_trade_status="FAILD";

			String return_msg = Dom4JUtil.getElementAttribute(document, "xml/return_msg");
			error_msg=return_msg;
			logger.error("发起微信同意支付下单失败,:"+return_msg);
			throw new BusinessException(ErrorCode.PAY_THIRD_FAILED);
		}
		error_code = result_code;
        
        //拼接返回后的签名及参数
      //再次生成APP签名
        String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
        String paySign = "";//签名
        String signType = "MD5";
        String str = "appid=" + app_id + "&noncestr=" + nonce_str + "&package=Sign=WXPay&partnerid=" + mch_id
               + "&prepayid="+prepay_id+ "&timestamp=" + timeStamp + "&key=" + wx_pay_api_key;
        
        System.out.println("str:"+str);
        paySign = MD5.MD5Encode(str).toUpperCase();
        System.out.println("paySign:"+paySign);
     
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", app_id);
        jsonObject.put("nonceStr", nonce_str);
        jsonObject.put("package", "Sign=WXPay");
        jsonObject.put("partnerId", mch_id);
        jsonObject.put("prepayId", prepay_id);
        jsonObject.put("timeStamp", timeStamp);
        jsonObject.put("sign", paySign);
        System.out.println("返回给APP:"+jsonObject.toString());

        //增加支付请求和通知日志
		PayLogUtil.insert(payService,"WECHAT",prepay_id,bean.getBuyer_user_id() == null ? "" : bean.getBuyer_user_id().toString(),bean.getBuyer_user_id() == null ? "" : bean.getBuyer_user_id().toString(),
				"PAY","SEND",bean, gInfo,200,send_status,send_trade_status,raw,result_raw,
				url,error_code,error_msg);

//		try {
//			Log.e("增加支付请求和通知日志 开始");
//			PaymentLogBean plb = PayLogUtil.insertBean("WECHAT","","","",
//				"PAY","SEND",bean,200,send_status,send_trade_status,raw,result_raw,
//				url,error_code,error_msg);
//			payService.add_payment_log(plb);
//			Log.e("增加支付请求和通知日志 结束");
//		} catch (Exception e) {
//			e.printStackTrace();
//			Log.e("增加支付请求和通知日志 异常");
//		}

		return jsonObject;
	}


	/**
	 * 微信支付异步通知
	 * @param request
	 * @param response
	 * @return
	 */
	@Override
	public Map<String,Object> get_pay_result(PayServiceImpl payService,HttpServletRequest request, HttpServletResponse response)
	{
		//发送状态
		String send_status="SUCCESS";
		//发送后交易状态
		String send_trade_status="SUCCESS";
		String error_code="";
		String error_msg="";
		String raw="";
		String result_raw="";

		InputStream is = null;
		Map<String,Object> map = new HashMap<String,Object>();
		String return_code="SUCCESS";
		String order_id ="";
		try
		{
			is = request.getInputStream();
			String resultxml = InputStreamUtils.InputStreamTOString(is);
			result_raw = resultxml;
			System.out.println("微信支付notify——xml:" + resultxml);
			//获取商户id
			Document doc = DocumentHelper.parseText(resultxml);
			Element rootElement = doc.getRootElement();
			return_code = rootElement.elementText("return_code");
			String result_code = rootElement.elementText("result_code");
			error_code = result_code;
			order_id = rootElement.elementText("out_trade_no");
			map.put("order_id",order_id);
			if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code))
			{
				PaymentBean pb = payService.get_payment_by_provider("WEICHAT");
				JSONObject thirid_config = JSONObject.parseObject(pb.getParam_config());
				String wx_pay_api_key = thirid_config.getString("key_private");//微信商户密钥，自己设置的
				//验证签名是否正确
				boolean signIsRight = SignUtils.checkSign(resultxml, wx_pay_api_key);
				if (signIsRight)
				{
				}
				else
					return_code = "FAILD";
			}
			else
			{
				send_trade_status = "FAILD";
				return_code = "FAILD";
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return_code = "FAILD";
		}
		finally
		{
			try
			{
				is.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
				return_code = "FAILD";
			}
		}
		logger.info("***********异步通知url——end:");
		map.put("return_code",return_code);
		//增加支付请求和通知日志
//		PayLogUtil.insert(payService,"WECHAT","","","",
//				"PAY","RECEIVE",bean,200,send_status,send_trade_status,raw,result_raw,
//				"",error_code,error_msg);

		return map;
	}


}
